<script setup>
import { ref, computed, watch, watchEffect } from 'vue'
import BaseRankingChart from '@/components/chart/BaseRankingChart.vue'
import BasePieChart from '@/components/chart/BasePieChart.vue'
import BaseChart from '@/components/chart/BaseChart.vue'
import CustomDatePicker from '@/components/header/CustomDatePicker.vue'
import { useCompanyStore } from '@/stores/company'
import dayjs from 'dayjs'
import { getAllSubCategoryReportApi, getSubCategoryReportApi } from '@/api/category'
import CustomDateRadio from '@/components/header/CustomDateRadio.vue'
import { handleError } from '@/utils/handleError'
import { useMobileDetection } from '@/composables/useMobileDetection'

let companyStore = useCompanyStore()
const selectedSubCategory = ref(null)

// 加载状态
const pieChartLoading = ref(false)
const rankingChartLoading = ref(false)
const trendChartLoading = ref(false)
const tableLoading = ref(false)

// 饼图数据和时间控制
const pieChartTime = ref(null)
const PieChartData = ref([])

// 排名图数据和时间控制
const rankingChartTime = ref(null)
const RankingChartData = ref([])

// 趋势图数据和时间控制
const chartData = ref([])
const chartTimeRange = ref(null)

// 表格相关
const tableRef = ref(null)
let tableDataRange = ref([
    dayjs().startOf('month').valueOf(),  // 月初
    dayjs().startOf('day').valueOf()     // 今天开始时间
])
const subcategoryData = ref([])

// 端类型检测统一
const { isMobile, isTablet, isPC } = useMobileDetection();
const rankingHorizontal = computed(() => isPC.value);

// 获取用途总数据的通用方法
async function getSubCategoryTotalData(start_time, end_time, interval = '') {
    if (!start_time || !end_time) return null
    try {
        let res = await getAllSubCategoryReportApi({
            id: companyStore.currentCompany.id,
            start_time,
            end_time,
            interval,
            type: 3,
        })
        return res.aggregated_data
    } catch (error) {
        handleError(error, '获取用途数据失败')
        return null
    }
}

// 监听饼图时间变化
watchEffect(async () => {
    if (pieChartTime.value) {
        pieChartLoading.value = true
        try {
            let data = await getSubCategoryTotalData(pieChartTime.value.start_time, pieChartTime.value.end_time)
            if (data) {
                PieChartData.value = data.flat()
                    .map(item => ({
                        name: item.subcategory || '其他',
                        value: item.usage.reduce((acc, meter) => acc + Number(meter.Used), 0),
                        subcategory: item.subcategory
                    }))
                    .filter(item => item.value > 0)
                    .sort((a, b) => b.value - a.value)
            }
        } catch (error) {
            handleError(error, '获取饼图数据失败')
        } finally {
            pieChartLoading.value = false
        }
    }
})

// 监听排名图时间变化
watchEffect(async () => {
    if (rankingChartTime.value) {
        rankingChartLoading.value = true
        try {
            let data = await getSubCategoryTotalData(rankingChartTime.value.start_time, rankingChartTime.value.end_time)
            if (data) {
                RankingChartData.value = data.flat()
                    .map(item => ({
                        name: item.subcategory || '其他',
                        value: item.usage.reduce((acc, meter) => acc + Number(meter.Used), 0),
                        subcategory: item.subcategory
                    }))
                    .sort((a, b) => b.value - a.value)

                // 如果有数据且未选择用途，自动选择第一个
                if (RankingChartData.value.length && !selectedSubCategory.value) {
                    selectedSubCategory.value = RankingChartData.value[0].subcategory
                }

            }
        } catch (error) {
            handleError(error, '获取排名数据失败')
        } finally {
            rankingChartLoading.value = false
        }
    }
})
async function getSubCategoryData() {
    if (!selectedSubCategory.value || !chartTimeRange.value) return
    trendChartLoading.value = true
    try {
        let res = await getSubCategoryReportApi({
            id: companyStore.currentCompany.id,
            sub_category: selectedSubCategory.value,
            ...chartTimeRange.value,
            type: 3
        })

        // 添加空值检查
        if (!res?.aggregated_data) {
            chartData.value = []
            return
        }

        chartData.value = res.aggregated_data
            .filter((item) => Array.isArray(item) && item.length > 0)  // 确保item是数组且长度大于0
            .map(item => {
                let formatStr = 'YYYY-MM-DD'
                switch (chartTimeRange.value?.interval) {  // 添加可选链操作符
                    case 'day':
                        formatStr = 'MM-DD'
                        break
                    case 'month':
                        formatStr = 'YYYY-MM'
                        break
                    case 'year':
                        formatStr = 'YYYY'
                        break
                    case 'quarter':
                        formatStr = 'Q季度'
                        break
                }

                // 添加安全的数据获取
                const startTime = item[0]?.StartTime
                const value = item.reduce((acc, cur) => acc + (Number(cur.Used) || 0), 0).toFixed(2)

                return {
                    time: startTime ? dayjs(startTime).format(formatStr) : '-',
                    timestamp: startTime ? dayjs(startTime).valueOf() : 0,
                    value: value
                }
            })
            // .filter(item => Number(item.value) > 0)
            .sort((a, b) => a.timestamp - b.timestamp)
    } catch (error) {
        handleError(error, '获取趋势图数据失败')
        chartData.value = []  // 发生错误时设置为空数组
    } finally {
        trendChartLoading.value = false
    }
}

// 监听趋势图数据变化
watchEffect(getSubCategoryData)

// 趋势图配置
const chartOptions = computed(() => ({
    xAxisData: chartData.value.map(item => item.time),
    yAxisUnit: 'm³',
    series: [
        {
            name: '用气量',
            type: 'line',
            data: chartData.value.map(item => item.value),
        }
    ],
    customColors: ['#409EFF', '#909399']
}))

// 监听表格数据变化
watchEffect(async () => {
    if (tableDataRange.value) {
        tableLoading.value = true
        try {
            let tempData = []
            let data = await getSubCategoryTotalData(tableDataRange.value[0], tableDataRange.value[1], 'day')
            if (data && data.length > 0) {
                // 处理第一天的数据
                data[0].forEach(item => {
                    tempData.push({
                        subcategory: item.subcategory || '其他',
                        [dayjs(item.usage[0].StartTime).format('YYYY/MM-DD')]:
                            item.usage.reduce((acc, meter) => acc + Number(meter.Used), 0)
                    })
                })

                // 处理剩余天数的数据
                for (let i = 1; i < data.length; i++) {
                    data[i].forEach(toPushItem => {
                        let subItem = tempData.find(item => item.subcategory === (toPushItem.subcategory || '其他'))
                        if (subItem) {
                            subItem[dayjs(toPushItem.usage[0].StartTime).format('YYYY/MM-DD')] =
                                toPushItem.usage.reduce((acc, meter) => acc + Number(meter.Used), 0)
                        }
                    })
                }
                subcategoryData.value = tempData
            } else {
                subcategoryData.value = []
            }
        } catch (error) {
            handleError(error, '获取表格数据失败')
        } finally {
            tableLoading.value = false
        }
    }
})

// 计算表格日期并排序
const dates = computed(() => {
    if (!subcategoryData.value.length) return []
    const allDates = Object.keys(subcategoryData.value[0]).filter(key => key !== 'subcategory')
    return allDates.sort((a, b) => {
        const timeA = dayjs(a.replace('/', '-')).valueOf()
        const timeB = dayjs(b.replace('/', '-')).valueOf()
        return timeA - timeB
    })
})

// 格式化日期显示
const formatDate = (date) => {
    if (date.includes('/')) {
        return date
    }
    return date.replace('-', '/')
}

// 处理表格数据并排序
const tableData = computed(() => {
    let data = subcategoryData.value.map(item => {
        const rowData = {
            subcategory: item.subcategory,
        }
        dates.value.forEach(date => {
            rowData[date] = item[date] ? Number(item[date]).toFixed(2) : '-'
        })
        return rowData
    })
    return data
})

// 导出方法
const exportEvent = () => {
    const $table = tableRef.value
    if ($table) {
        $table.openExport({
            filename: "用途用气台账",
            type: "xlsx",
            exportMethod: ({ options }) => {
                return $table.exportData(
                    Object.assign({}, options, {
                        original: false,
                        formatter: true,
                        footer: true,
                        columnFilterMethod: ({ column }) => {
                            return column.property !== "seq"
                        },
                    })
                )
            },
        })
    }
}

</script>
<template>
    <div class="container">
        <div class="left">
            <div class="top">
                <el-card v-loading="pieChartLoading" class="chart-box" style="display: flex; flex-direction: column"
                    body-style="flex: 1;">
                    <template #header>
                        <div class="card-header">
                            <span>用途用气量</span>
                            <CustomDateRadio @update:modelValue="pieChartTime = $event"></CustomDateRadio>
                        </div>
                    </template>
                    <BasePieChart height="210px" :showLegend="false" :data="PieChartData" unit="m³" />
                </el-card>
                <el-card v-loading="trendChartLoading" class="chart-box" style="display: flex; flex-direction: column"
                    body-style="flex: 1;">
                    <template #header>
                        <div class="card-header">
                            <div class="left-content">
                                <span>用途用气数据</span>
                                <el-select filterable size="small" v-model="selectedSubCategory">
                                    <el-option v-for="item in RankingChartData.filter(item => item.name !== '其他')"
                                        :key="item.subcategory" :label="item.name"
                                        :value="item.subcategory"></el-option>
                                </el-select>
                            </div>
                            <div class="right-content">
                                <CustomDateRadio :isFragmentation="true" @update:modelValue="chartTimeRange = $event">
                                </CustomDateRadio>
                            </div>
                        </div>
                    </template>
                    <BaseChart :options="chartOptions" />
                </el-card>
            </div>
            <div class="bottom">
                <el-card v-loading="tableLoading" class="table-box" body-style="flex:1">
                    <template #header>
                        <div class="card-header">
                            <div class="left-content">
                                <span>用途用气台账</span>
                                <CustomDatePicker v-model="tableDataRange" size="small" width="14rem">
                                </CustomDatePicker>
                            </div>
                            <div class="right-content">
                                <el-button type="primary" size="small" @click="exportEvent">
                                    <template #icon>
                                        <SvgIcon icon="download" />
                                    </template>
                                    导出
                                </el-button>
                            </div>
                        </div>
                    </template>
                    <vxe-table :export-config="{ type: 'xlsx', useStyle: true }" ref="tableRef" border :data="tableData"
                        height="auto">
                        <vxe-column fixed="left" field="subcategory" title="用途" width="100" align="center" />
                        <template v-for="date in dates" :key="date">
                            <vxe-column :field="date" :title="formatDate(date)" width="120" align="center">
                                <template #default="{ row }">
                                    {{ row[date] }}
                                </template>
                            </vxe-column>
                        </template>
                    </vxe-table>
                </el-card>
            </div>
        </div>
        <div class="right">
            <el-card v-loading="rankingChartLoading" class="sidebar" body-style="flex:1">
                <template #header>
                    <div class="card-header">
                        <span>用途用气排名</span>
                        <CustomDateRadio @update:modelValue="rankingChartTime = $event"></CustomDateRadio>
                    </div>
                </template>
                <BaseRankingChart :horizontal="rankingHorizontal" title="用途用气排名" :data="RankingChartData">
                </BaseRankingChart>
            </el-card>
        </div>
    </div>
</template>
<style scoped>
.container {
    width: 100%;
    height: 100%;
    display: flex;
    gap: var(--gap-normal);
    box-sizing: border-box;
}

.left {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--gap-normal);
    min-width: 0;
}

.right {
    width: 400px;
    height: 100%;
    flex-shrink: 0;
}

.top {
    display: flex;
    gap: var(--gap-normal);
    height: 300px;
}

.chart-box {
    flex: 1;
    height: 100%;
    min-width: 0;
}

.bottom {
    flex: 1;
    min-height: 0;
}

.table-box {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.sidebar {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
}

.left-content {
    display: flex;
    align-items: center;
    gap: var(--gap-small);
}

.right-content {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex: 1;
    gap: var(--gap-small);
}

@media (max-width: 1400px) {
    .container {
        flex-direction: column;
    }

    .left,
    .right {
        width: 100% !important;
        min-width: 0;
        height: auto;
    }

    .top {
        flex-direction: column;
        height: auto;
    }

    .chart-box {
        min-width: 0;
        height: 220px;
    }

    .sidebar {
        width: 100% !important;
        min-width: 0;
        height: auto;
    }

    .table-box {
        height: 500px;
    }
}
</style>